package com.nulstudio.cloud.commodity.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.nulstudio.cloud.commodity.domain.dto.CommodityDto;
import com.nulstudio.cloud.common.domain.vo.CommodityVo;
import com.nulstudio.cloud.commodity.mapper.CommodityMapper;
import com.nulstudio.cloud.common.entity.NulCommodity;
import com.nulstudio.cloud.common.exception.NulException;
import com.nulstudio.cloud.common.exception.NulExceptionConstants;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

@Service
public final class CommodityService {

    private final Logger log = LoggerFactory.getLogger(CommodityService.class);

    @Resource
    @NonNull
    private CommodityMapper commodityMapper;

    public PageInfo<CommodityVo> fetchAll(@NonNull String name, int page, int pageSize) {
        final PageInfo<CommodityVo> result;
        try (
                final Page<CommodityVo> ignored = PageHelper.startPage(page, pageSize);
        ) {
            final List<CommodityVo> commodityVoList = commodityMapper.fetchCommodityList(name);
            result = new PageInfo<>(commodityVoList);
        } catch (Exception exception) {
            log.error("Error", exception);
            throw new NulException(NulExceptionConstants.INTERNAL_SERVER_ERROR, exception.getMessage());
        }
        return result;
    }

    @NonNull
    public CommodityVo getCommodityById(int id) {
        final CommodityVo result = commodityMapper.getCommodityById(id);
        if (result == null) {
            throw new NulException(NulExceptionConstants.COMMODITY_NOT_EXIST);
        }
        return result;
    }

    public void create(@NonNull CommodityDto commodityDto) {
        final int result = commodityMapper.insert(new NulCommodity(
                commodityDto.name(), transformMoney(commodityDto.wholesalePrice()), transformMoney(commodityDto.retailPrice()),
                transformMoney(commodityDto.costPrice()), commodityDto.notes()
        ));
        if (result <= 0) {
            throw new NulException(NulExceptionConstants.INTERNAL_SERVER_ERROR);
        }
    }

    public void update(int id, @NonNull CommodityDto commodityDto) {
        final int result = commodityMapper.update(new NulCommodity(
                id, commodityDto.name(), transformMoney(commodityDto.wholesalePrice()), transformMoney(commodityDto.retailPrice()),
                transformMoney(commodityDto.costPrice()), commodityDto.notes()
        ));
        if (result <= 0) {
            throw new NulException(NulExceptionConstants.COMMODITY_NOT_EXIST);
        }
    }

    public void delete(int id) {
        final List<Integer> idList = List.of(id);
        this.delete(idList);
    }

    public void delete(@NonNull List<Integer> id) {
        final int result = commodityMapper.delete(id);
        if (result <= 0) {
            throw new NulException(NulExceptionConstants.COMMODITY_NOT_EXIST);
        }
    }

    @NonNull
    private BigDecimal transformMoney(@NonNull BigDecimal source) {
        return source.setScale(2, RoundingMode.HALF_UP);
    }
}
